package edu.gatech.cs2340.aperturescience.backend.login;

import java.util.ArrayList;
import java.util.List;

import edu.gatech.cs2340.aperturescience.backend.TodoSQLiteHelper;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

/**
 * @author Jacob Morgan, Kefu Zhou, Kevin Lacey, Kelly Evanish
 * 
 *         Helper class for registering new users.
 */

public class SQLUsersDataSource implements UsersDataSource {
	private SQLiteDatabase database;
	private TodoSQLiteHelper dbHelper;

	// private String[] columns = new String[]{}

	/**
	 * Constructor for creating database variable
	 * 
	 * @param context
	 *            the activity where you started from
	 */
	public SQLUsersDataSource(Context context) {
		dbHelper = new TodoSQLiteHelper(context);
	}

	/**
	 * Opens the database.
	 */
	public void open() throws SQLException {
		database = dbHelper.getWritableDatabase();
	}

	/**
	 * Closes the database.
	 */
	public void close() {
		if (database != null)
			database.close();
	}

	/**
	 * Getting a list of all registered users.
	 * 
	 * @return users list of users
	 */
	@Override
	public List<User> getAllUsers() {
		Cursor c = database.query(dbHelper.TABLE_USERS, null, null, null, null,
				null, dbHelper.COLUMN_NAME);
		c.moveToFirst();
		ArrayList<User> users = new ArrayList<User>();
		while (!c.isAfterLast()) {
			User user = getUser(c);
			users.add(user);
			c.moveToNext();
		}
		c.close();
		return users;
	}

	/**
	 * Checking whether username and password are valid.
	 * 
	 * @param username
	 *            user's username
	 * @param password
	 *            user's password
	 * @return boolean value for whether login is valid or not
	 */
	@Override
	public User getUser(String username, String password) {
		password = encryptPassword(password);
		Cursor c = database.query(dbHelper.TABLE_USERS, null,
				"username=? AND password=?",
				new String[] { username, password }, null, null, null, "1");
		c.moveToFirst();
		if (c.isAfterLast())
			return null;
		else
			return getUser(c);
	}

	/**
	 * Creating user with appropriate information.
	 * 
	 * @param username
	 *            user's username
	 * @param password
	 *            user's password
	 * @param email
	 *            user's Email
	 * @param name
	 *            user's name
	 * @return whether account was succesfully created
	 */
	@Override
	public boolean createUser(String username, String password, String email,
			String name) {
		if (userExists(username))
			return false;
		password = encryptPassword(password);
		ContentValues values = new ContentValues();
		values.put("username", username);
		values.put("password", password);
		values.put("email", email);
		values.put("name", name);
		database.insert(dbHelper.TABLE_USERS, null, values);
		return true;
	}

	/**
	 * Checks whether the user account exists.
	 * 
	 * @param username
	 *            User's username
	 * @return boolean value for whether or not it exists
	 */
	public boolean userExists(String username) {
		Cursor c = database.query(dbHelper.TABLE_USERS,
				new String[] { dbHelper.COLUMN_ID }, "username=?",
				new String[] { username }, null, null, null, "1");
		c.moveToFirst();
		return !c.isAfterLast();
	}

	/**
	 * Getting the user's username, email, and name.
	 * 
	 * @param cursor
	 *            what's returned when you access the database
	 * @return user user object with appropriate information
	 */
	private User getUser(Cursor cursor) {
		int id = cursor.getInt(0);
		String username = cursor.getString(1);
		String email = cursor.getString(2);
		String name = cursor.getString(4);
		User user = new User(id, username, email, name);
		return user;
	}

	/**
	 * Encrypting user password.
	 * 
	 * @param password
	 *            user's password
	 * @return password password
	 */
	private String encryptPassword(String password) {
		return password;
	}
}